package com.ls.inittemplate.utils.verificationCode;

import com.ls.inittemplate.exception.ErrorCode;
import com.ls.inittemplate.exception.ThrowUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerificationCodeService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private final Random random = new Random();
    private static final String VERIFICATION_CODE_KEY = "verification:code:";
    private static final String SEND_COUNT_KEY = "verification:count:";

    // 生成随机验证码
    public String generateCode(int length) {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < length; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    // 保存验证码到Redis
    public void saveCode(String userAccount, String email, String code, int expireMinutes) {
        String verificationCodeKey = getVerificationCodeKey(userAccount, email);
        redisTemplate.opsForValue().set(verificationCodeKey, code, expireMinutes, TimeUnit.MINUTES);
    }

    // 验证验证码
    public void verifyCode(String userAccount, String email, String inputCode) {
        String verificationCodeKey = getVerificationCodeKey(userAccount, email);
        String storedCode = (String) redisTemplate.opsForValue().get(verificationCodeKey);
        ThrowUtils.throwIf(!(storedCode != null && storedCode.equals(inputCode)), ErrorCode.OPERATION_ERROR, "验证码错误");
    }

    // 记录发送次数
    public void recordSendCount(String userAccount, String email) {
        String sendCountKey = getSendCountKey(userAccount, email);
        Long count = redisTemplate.opsForValue().increment(sendCountKey, 1);
        if (count != null && count == 1) {
            redisTemplate.expire(sendCountKey, 1, TimeUnit.HOURS);
        }
    }

    // 检查是否超过发送限制
    public void isExceedLimit(String userAccount, String email, int limitCount) {
        String sendCountKey = getSendCountKey(userAccount, email);
        Integer count = (Integer) redisTemplate.opsForValue().get(sendCountKey);
        ThrowUtils.throwIf(count != null && count >= limitCount, ErrorCode.OPERATION_ERROR, "发送次数超过限制");
    }

    private String getVerificationCodeKey(String userAccount, String email) {
        return String.format("%s:%s:%s", VerificationCodeService.VERIFICATION_CODE_KEY, userAccount, email);
    }

    private String getSendCountKey(String userAccount, String email) {
        return String.format("%s:%s:%s", VerificationCodeService.SEND_COUNT_KEY, userAccount, email);
    }
}
